home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-06-11 | 4.6 KB | 171 lines | [TEXT/CWIE] |
- #include "Solution.h"
-
- #include "ProblemUtils.h"
-
- #include <stdio.h>
- #include <string.h>
- #include <Files.h>
- #include <Errors.h>
-
- const int MAX_HOMES = 10000;
-
- static OSErr Read2UInt32FromHandle( Handle data, UInt32 *number1, UInt32 *number2 )
- {
- OSErr err;
- char line[MAX_LINE_LEN];
- char *p;
-
- p = line;
- if ( ProblemReadLineFromHandle( data, line, MAX_LINE_LEN )
- && ProblemGetUInt32( &p, number1 )
- && ProblemGetUInt32( &p, number2 ) && *p == 0 ) {
- err = noErr;
- } else {
- err = -1;
- }
- return err;
- }
-
- static OSErr Read2SInt32FromHandle( Handle data, SInt32 *number1, SInt32 *number2 )
- {
- OSErr err;
- char line[MAX_LINE_LEN];
- char *p;
-
- p = line;
- if ( ProblemReadLineFromHandle( data, line, MAX_LINE_LEN )
- && ProblemGetSInt32( &p, number1 )
- && ProblemGetSInt32( &p, number2 ) && *p == 0 ) {
- err = noErr;
- } else {
- err = -1;
- }
- return err;
- }
-
- static int Quadrant( Node *pt, SInt32 x, SInt32 y )
- {
- if ( pt->xCoord > x ) {
- if ( pt->yCoord > y ) {
- return 0;
- } else {
- return 3;
- }
- } else {
- if ( pt->yCoord > y ) {
- return 1;
- } else {
- return 2;
- }
- }
- }
-
- #define VERTEX(i) homesToEnclose[nodesInPerimeter[i]]
-
- static Boolean Inside( Node homesToEnclose[], UInt32 numNodesInPerimeter, UInt32 nodesInPerimeter[], UInt32 home )
- {
- SInt32 i, angle, quad, next_quad, delta;
- Node last_vertex, next_vertex;
- Node pt = homesToEnclose[home];
-
- angle = 0;
- last_vertex = VERTEX(numNodesInPerimeter-1);
- quad = Quadrant( &last_vertex, pt.xCoord, pt.yCoord );
- for ( i = 0; i < numNodesInPerimeter; i++ ) {
- next_vertex = VERTEX(i);
- next_quad = Quadrant( &next_vertex, pt.xCoord, pt.yCoord );
- delta = next_quad - quad;
- switch ( delta ) {
- case 3:
- delta = -1;
- break;
- case -3:
- delta = 1;
- break;
- case 2:
- case -2:
- if ( (next_vertex.xCoord - pt.xCoord) * (last_vertex.yCoord - next_vertex.yCoord) > (next_vertex.yCoord - pt.yCoord) * (last_vertex.xCoord - next_vertex.xCoord) ) {
- delta = -delta;
- }
- break;
- }
- angle = angle + delta;
- quad = next_quad;
- last_vertex = next_vertex;
- }
- return (angle == 4) || (angle == 0) || (angle == -4);
- }
-
- static Node homesToEnclose[MAX_HOMES];
- static Node saved_homesToEnclose[MAX_HOMES];
- static UInt32 nodesInPerimeter[MAX_HOMES];
-
- pascal OSErr CheckPerimiter( const FSSpec* infile, const FSSpec* outfile, Boolean *correct )
- {
- OSErr err;
- Handle indata;
- UInt32 perimiter_squared, returned_perimiter_squared;
- UInt32 i, j;
- UInt32 numHomes;
- UInt32 numNodesInPerimeter;
-
- *correct = false;
-
- err = ProblemFileRead( infile, &indata );
- ProblemLogError( err, "CheckPerimiter: ProblemFileRead" );
- if ( err == noErr ) {
- err = Read2UInt32FromHandle( indata, &numHomes, &perimiter_squared );
- if ( err == noErr ) {
- for ( UInt32 i = 0; i < numHomes && err == noErr; i++ ) {
- err = Read2SInt32FromHandle( indata, &homesToEnclose[i].xCoord, &homesToEnclose[i].yCoord );
- saved_homesToEnclose[i] = homesToEnclose[i];
- }
- }
- ProblemLogError( err, "CheckPerimiter: Problem Reading" );
- if ( err == noErr ) {
- Perimeter( numHomes, homesToEnclose, &numNodesInPerimeter, nodesInPerimeter );
- *correct = 0 <= numNodesInPerimeter && numNodesInPerimeter <= numHomes;
-
- // Check based inputs
- for ( i = 0; i < numHomes && *correct; i++ ) {
- *correct = homesToEnclose[i].xCoord == saved_homesToEnclose[i].xCoord
- && homesToEnclose[i].yCoord == saved_homesToEnclose[i].yCoord;
- }
-
- // Check for duplicate or illegal nodes in fence
- for ( i = 0; i < numNodesInPerimeter && *correct; i++ ) {
- *correct = 0 <= nodesInPerimeter[i] && nodesInPerimeter[i] < numHomes;
- for ( j = 0; j < numNodesInPerimeter && *correct; j++ ) {
- if ( i != j && nodesInPerimeter[i] == nodesInPerimeter[j] ) {
- *correct = false;
- }
- }
- }
-
- if ( *correct ) {
- returned_perimiter_squared = 0;
- if ( numNodesInPerimeter >= 2 ) {
- for ( i = 0; i < numNodesInPerimeter && *correct; i++ ) {
- UInt32 n1 = nodesInPerimeter[i];
- UInt32 n2 = nodesInPerimeter[(i+1) % numNodesInPerimeter];
- returned_perimiter_squared += (homesToEnclose[n1].xCoord - homesToEnclose[n2].xCoord)
- * (homesToEnclose[n1].xCoord - homesToEnclose[n2].xCoord);
- returned_perimiter_squared += (homesToEnclose[n1].yCoord - homesToEnclose[n2].yCoord)
- * (homesToEnclose[n1].yCoord - homesToEnclose[n2].yCoord);
- }
- }
- *correct = returned_perimiter_squared == perimiter_squared;
- }
-
- if ( *correct ) {
- for ( i = 0; i < numHomes && *correct; i++ ) {
- *correct = Inside( homesToEnclose, numNodesInPerimeter, nodesInPerimeter, i );
- }
- }
-
- }
- DisposeHandle( indata );
- }
- return err;
- }
-